package com.jingdianjichi.auth.domin.service.Impl;


import cn.dev33.satoken.secure.SaSecureUtil;
import com.google.gson.Gson;
import com.jingdianjichi.auth.common.enums.AuthUserStatusEnum;
import com.jingdianjichi.auth.common.enums.IsDeleteFlagEnum;
import com.jingdianjichi.auth.domin.constants.AuthConstant;
import com.jingdianjichi.auth.domin.convert.AuthUserBOConverter;
import com.jingdianjichi.auth.domin.entity.AuthUserBO;
import com.jingdianjichi.auth.domin.redis.RedisUtil;
import com.jingdianjichi.auth.domin.service.AuthUserDomainService;
import com.jingdianjichi.auth.infra.baisc.entity.*;
import com.jingdianjichi.auth.infra.baisc.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Autowired
    private AuthPermissionService authPermissionService;

    @Autowired
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private AuthRoleService authRoleService;

    private String salt = "chicken";

    @Autowired
    private RedisUtil redisUtil;

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";

    private static final String LOGIN_PREFIX = "loginCode";


    @Override
    @Transactional(rollbackFor = Exception.class)   // 设计到多个表，缓存，用一个事务完成，保证强一致性
    public Boolean register(AuthUserBO authUserBO) {
        // 校验用户是否存在，即openId是否存在
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> existUser = authUserService.queryByCondition(existAuthUser);
        if(existUser.size()>0) return true;
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToEntity(authUserBO);
        if(StringUtils.isNotBlank(authUser.getPassword())){
            // 传统的摘要算法（md5），会被撞库。解决：使用加盐技术，进行二次加密
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(),salt));
        }
        if (StringUtils.isBlank(authUser.getAvatar())) {
            authUser.setAvatar("http://117.72.114.44:9000/user/icon%2F%E5%9B%BE%E7%89%871.jpg");
        }
        if (StringUtils.isBlank(authUser.getNickName())) {
            authUser.setNickName("默认用户");
        }

        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        authUser.setIsDelete(IsDeleteFlagEnum.UN_DELETED.getCode());

        Integer count = authUserService.insert(authUser);

        // 建立初步的用户-角色关联
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(AuthConstant.NORMAL_USER);
        AuthRole roleResult = authRoleService.queryByCondition(authRole);
        Integer roleId = roleResult.getId();

        AuthUserRole authUserRole = new AuthUserRole();
        authUserRole.setUserId(authUser.getId());
        authUserRole.setRoleId(roleId);
        authUserRole.setIsDelete(IsDeleteFlagEnum.UN_DELETED.getCode());
        authUserRoleService.insert(authUserRole);

        // 把用户所有的角色对象都刷到redis缓存里面
        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> authRoleList = new LinkedList<>();
        authRoleList.add(authRole);  // 目前只有一个角色
        redisUtil.set(roleKey,new Gson().toJson(authRoleList));   // 把list转为json字符串；也能转回来

        // 把用户所有的权限对象都刷到redis缓存里面
        AuthRolePermission authRolePermission = new AuthRolePermission();
        authRolePermission.setRoleId(Long.valueOf(roleId));
        List<AuthRolePermission> authRolePermissionList = authRolePermissionService.queryByCondition(authRolePermission);
        List<Long> permissionIdList = authRolePermissionList.stream().
                map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
        // 根据permissionId 查 权限 对象
        List<AuthPermission> authPermissionList = authPermissionService.queryByPermissionIdList(permissionIdList);
        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        redisUtil.set(permissionKey, new Gson().toJson(authPermissionList));
        return count > 0;
    }


    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToEntity(authUserBO);
        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        authUser.setIsDelete(IsDeleteFlagEnum.UN_DELETED.getCode());

        Integer count = authUserService.update(authUser);
        return count > 0;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser existAuthUser = new AuthUser();
        existAuthUser.setUserName(authUserBO.getUserName());
        List<AuthUser> authUserList = authUserService.queryByCondition(existAuthUser);
        // 校验下，防止为空
        if(CollectionUtils.isEmpty(authUserList)){
            return new AuthUserBO();
        }
        AuthUser authUser = authUserList.get(0);
        return AuthUserBOConverter.INSTANCE.convertEntityToBO(authUser);
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = new AuthUser();
        authUser.setId(authUserBO.getId());
        authUser.setIsDelete(IsDeleteFlagEnum.UN_DELETED.getCode());
        Integer count = this.authUserService.updateByUserName(authUser);
        return count > 0;
    }

}
